<?php
/**
 * wechat php test
 */

//define your token
define("TOKEN", "weixin");
    $wechatObj = new wechatCallbackapiTest();
   if(isset($_GET['echostr'])){
        $wechatObj->valid();
   }else{
        $wechatObj->responseMsg();
   }


class wechatCallbackapiTest{

        public function valid()
        {
            $echoStr = $_GET["echostr"];

            //valid signature , option
            if($this->checkSignature()){
                echo $echoStr;
                exit;
            }
        }

        /**
         * 回复消息
         */
        public function responseMsg(){
            //获得post 数据
            $postStr=$GLOBALS["HTTP_RAW_POST_DATA"];

            if(empty($postStr)){
                echo 'POST Empty6!!!';
                exit;
            }else{
                //libxml_disable_entity_loader(true);//禁止加载外部实体
                //将post数据转成Obj
                $postObj=simplexml_load_string($postStr,'SimpleXMLElement',LIBXML_NOCDATA);
                $fromUserName=$postObj->FromUserName;
                $toUserName=$postObj->ToUserName;
                $msgType=$postObj->MsgType;

                switch($msgType){
                    case 'event':
                        $Event=$postObj->Event;
                        if($Event=='subscribe'){
                            $retMsg="欢迎关注彩聚天石服务号,唔该!!!";
                            $textTpl="<xml>
                                    <ToUserName><![CDATA[%s]]></ToUserName>
                                    <FromUserName><![CDATA[%s]]></FromUserName>
                                    <CreateTime>%s</CreateTime>
                                    <MsgType><![CDATA[text]]></MsgType>
                                    <Content><![CDATA[%s]]></Content>
                                    </xml>";
                        }

                        break;
                    case 'text':
                        $retMsg=$postObj->Content;
                        $textTpl="<xml>
                                    <ToUserName><![CDATA[%s]]></ToUserName>
                                    <FromUserName><![CDATA[%s]]></FromUserName>
                                    <CreateTime>%s</CreateTime>
                                    <MsgType><![CDATA[text]]></MsgType>
                                    <Content><![CDATA[%s]]></Content>
                                    </xml>";
                        break;
                    case 'image':
                        $retMsg=$postObj->MediaId;
                        $textTpl="<xml>
                                    <ToUserName><![CDATA[%s]]></ToUserName>
                                    <FromUserName><![CDATA[%s]]></FromUserName>
                                    <CreateTime>%s</CreateTime>
                                    <MsgType><![CDATA[image]]></MsgType>
                                    <Image>
                                    <MediaId><![CDATA[%s]]></MediaId>
                                    </Image>
                                    </xml>";
                        break;
                    default:
                        $retMsg="不支持该类型信息!!!";
                        break;
                }


                $resultStr=sprintf($textTpl,$fromUserName,$toUserName,time(),$retMsg);
                echo $resultStr;
            }

        }

        /**
         * @return bool 判断
         * @throws Exception TOKEN 未定义
         */
        private function checkSignature()
        {
            // you must define TOKEN by yourself
            if (!defined("TOKEN")) {
                throw new Exception('TOKEN is not defined!');
            }

            $signature = $_GET["signature"];
            $timestamp = $_GET["timestamp"];
            $nonce = $_GET["nonce"];

            $token = TOKEN;
            $tmpArr = array($token, $timestamp, $nonce);
            // use SORT_STRING rule
            sort($tmpArr, SORT_STRING);
            $tmpStr = implode( $tmpArr );
            $tmpStr = sha1( $tmpStr );

            if( $tmpStr == $signature ){
                return true;
            }else{
                return false;
            }
        }
}